package com.slt.android.a2048;

import android.content.Context;
import android.graphics.Color;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Created by dp on 2018/2/24.
 */

public class GameMap extends LinearLayout {
    View layoutView;
    Context mContext;
    TextView tv11, tv12, tv13, tv14;
    TextView tv21, tv22, tv23, tv24;
    TextView tv31, tv32, tv33, tv34;
    TextView tv41, tv42, tv43, tv44;
    List<Beans> list = new ArrayList<>();
    List<Beans> listAfter = new ArrayList<>();

    List<Integer> listNull = new ArrayList<>();

    public GameMap(Context context) {
        super(context);
    }

    public GameMap(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        initView();
        initData();
    }

    public GameMap(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    private void initView() {
        layoutView = LayoutInflater.from(getContext()).inflate(R.layout.maps, null);
        tv11 = (TextView) layoutView.findViewById(R.id.tv_11);
        tv12 = (TextView) layoutView.findViewById(R.id.tv_12);
        tv13 = (TextView) layoutView.findViewById(R.id.tv_13);
        tv14 = (TextView) layoutView.findViewById(R.id.tv_14);
        tv21 = (TextView) layoutView.findViewById(R.id.tv_21);
        tv22 = (TextView) layoutView.findViewById(R.id.tv_22);
        tv23 = (TextView) layoutView.findViewById(R.id.tv_23);
        tv24 = (TextView) layoutView.findViewById(R.id.tv_24);
        tv31 = (TextView) layoutView.findViewById(R.id.tv_31);
        tv32 = (TextView) layoutView.findViewById(R.id.tv_32);
        tv33 = (TextView) layoutView.findViewById(R.id.tv_33);
        tv34 = (TextView) layoutView.findViewById(R.id.tv_34);
        tv41 = (TextView) layoutView.findViewById(R.id.tv_41);
        tv42 = (TextView) layoutView.findViewById(R.id.tv_42);
        tv43 = (TextView) layoutView.findViewById(R.id.tv_43);
        tv44 = (TextView) layoutView.findViewById(R.id.tv_44);
        this.addView(layoutView);
    }

    /**
     * 生成新的随机数 并写出来
     */
    private void randNum() {
        listNull.clear();
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getNum() == 0) {
                listNull.add(i);
            }
        }
        int count = listNull.size();
        Random rand = new Random();
        //生成的随机数的位置
        if(count == 0) {
            Toast.makeText(mContext , "结束了。" ,Toast.LENGTH_SHORT).show();
            return;
        }
        int i = rand.nextInt(count);
        //pos是list中具体的位置
        int pos = listNull.get(i);

        //生成的随机数的大小
        Random rand2 = new Random();
        int num = rand2.nextInt(9);
        switch (num) {
            case 0:
                list.get(pos).setNum(2);
                break;
            case 1:
                list.get(pos).setNum(2);
                break;
            case 2:
                list.get(pos).setNum(2);
                break;
            case 3:
                list.get(pos).setNum(4);
                break;
            case 4:
                list.get(pos).setNum(4);
                break;
            case 5:
                list.get(pos).setNum(2);
                break;
            case 6:
                list.get(pos).setNum(8);
                break;
            case 7:
                list.get(pos).setNum(4);
                break;
            case 8:
                list.get(pos).setNum(2);
                break;
        }
        drawTextNum();
    }

    private void drawTextNum() {
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getNum() != 0) {
                list.get(i).getTv().setText("" + list.get(i).getNum());
            }else {
                list.get(i).getTv().setText("");
            }
            setTextBackGrounds(list.get(i).getTv());
        }
    }

    private void setTextBackGrounds(TextView tv) {
        int num = 0;
        String str = tv.getText().toString();
        if (str != null && str.length() > 0) {
            num = Integer.valueOf(tv.getText().toString());
        }
        switch (num) {
            case 0:
                tv.setBackgroundColor(Color.parseColor("#FF4081"));
                break;
            case 2:
                tv.setBackgroundColor(Color.parseColor("#990033"));
                break;
            case 4:
                tv.setBackgroundColor(Color.GREEN);
                break;
            case 8:
                tv.setBackgroundColor(Color.YELLOW);
                break;
            case 16:
                tv.setBackgroundColor(Color.BLUE);
                break;
            case 32:
                tv.setBackgroundColor(Color.RED);
                break;
            case 64:
                tv.setBackgroundColor(Color.CYAN);
                break;
            case 128:
                tv.setBackgroundColor(Color.LTGRAY);
                break;
            case 256:
                tv.setBackgroundColor(Color.GRAY);
                break;
            case 512:
                tv.setBackgroundColor(Color.DKGRAY);
                break;
            case 1024:
                tv.setBackgroundColor(Color.MAGENTA);
                break;
            case 2048:
                tv.setBackgroundColor(Color.BLACK);
                break;
        }
    }

    int startX, startY, endX, endY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = (int) event.getX();
                startY = (int) event.getY();
                break;

            case MotionEvent.ACTION_UP:
                endX = (int) event.getX();
                endY = (int) event.getY();
                judgeAndHandle();
                startX = startY = endX = endY = 0;
                break;
        }
        return true;
    }

    private void judgeAndHandle() {
        if (Math.abs(endY - startY) < Math.abs(endX - startX)) {
            handleMoveX();
        } else {
            handleMoveY();
        }
        randNum();
    }

    private void handleMoveY() {
        if (endY - startY > 0) {
            //往下滑
            scrollDown();
        } else {
            //往上滑
            scrollUp();
        }
    }

    private void handleMoveX() {
        if (endX - startX > 0) {
            //往右滑
            scrollRight();
        } else {
            //往左滑
            scrollLeft();
        }
    }

    private void scrollUp() {
        int answer1[] = order(list.get(12).getNum() , list.get(8).getNum() ,
                list.get(4).getNum(), list.get(0).getNum());

        int answer2[] = order(list.get(13).getNum() , list.get(9).getNum() ,
                list.get(5).getNum(), list.get(1).getNum());

        int answer3[] = order(list.get(14).getNum() , list.get(10).getNum() ,
                list.get(6).getNum(), list.get(2).getNum());

        int answer4[] = order(list.get(15).getNum() , list.get(11).getNum() ,
                list.get(7).getNum(), list.get(3).getNum());

        for (int i = 0; i < 4; i++) {
            list.get(i * 4 + 0).setNum(answer1[4-i-1]);
        }

        for (int i = 0; i < 4; i++) {
            list.get(i * 4 + 1).setNum(answer2[4-i-1]);
        }

        for (int i = 0; i < 4; i++) {
            list.get(i * 4 + 2).setNum(answer3[4-i-1]);
        }

        for (int i = 0; i < 4; i++) {
            list.get(i * 4 + 3).setNum(answer4[4-i-1]);
        }

        drawTextNum();
    }


    private void scrollDown() {
        int answer1[] = order(list.get(0).getNum() , list.get(4).getNum() ,
                list.get(8).getNum(), list.get(12).getNum());

        int answer2[] = order(list.get(1).getNum() , list.get(5).getNum() ,
                list.get(9).getNum(), list.get(13).getNum());

        int answer3[] = order(list.get(2).getNum() , list.get(6).getNum() ,
                list.get(10).getNum(), list.get(14).getNum());

        int answer4[] = order(list.get(3).getNum() , list.get(7).getNum() ,
                list.get(11).getNum(), list.get(15).getNum());

        for (int i = 0; i < 4; i++) {
            list.get(i * 4 + 0).setNum(answer1[i]);
        }

        for (int i = 0; i < 4; i++) {
            list.get(i * 4 + 1).setNum(answer2[i]);
        }

        for (int i = 0; i < 4; i++) {
            list.get(i * 4 + 2).setNum(answer3[i]);
        }

        for (int i = 0; i < 4; i++) {
            list.get(i * 4 + 3).setNum(answer4[i]);
        }

        drawTextNum();
    }

    private void scrollLeft() {
        //比如2204进去 --- 2240---4400。出来就变成了4400
        int answer1[] = order(list.get(3).getNum() , list.get(2).getNum() ,
                list.get(1).getNum(), list.get(0).getNum());

        int answer2[] = order(list.get(7).getNum() , list.get(6).getNum() ,
                list.get(5).getNum(), list.get(4).getNum());

        int answer3[] = order(list.get(11).getNum() , list.get(10).getNum() ,
                list.get(9).getNum(), list.get(8).getNum());

        int answer4[] = order(list.get(15).getNum() , list.get(14).getNum() ,
                list.get(13).getNum(), list.get(12).getNum());


        for (int i = 0; i < 4; i++) {
            list.get(i).setNum(answer1[4-i-1]);
        }

        for (int i = 4; i < 8; i++) {
            list.get(i).setNum(answer2[8-i-1]);
        }

        for (int i = 8; i < 12; i++) {
            list.get(i).setNum(answer3[12-i-1]);
        }

        for (int i = 12; i < 16; i++) {
            list.get(i).setNum(answer4[16-i-1]);
        }

        drawTextNum();
    }

    private void scrollRight() {
        int answer1[] = order(list.get(0).getNum() , list.get(1).getNum() ,
                list.get(2).getNum(), list.get(3).getNum());

        int answer2[] = order(list.get(4).getNum() , list.get(5).getNum() ,
                list.get(6).getNum(), list.get(7).getNum());

        int answer3[] = order(list.get(8).getNum() , list.get(9).getNum() ,
                list.get(10).getNum(), list.get(11).getNum());

        int answer4[] = order(list.get(12).getNum() , list.get(13).getNum() ,
                list.get(14).getNum(), list.get(15).getNum());

        for (int i = 0; i < 4; i++) {
            list.get(i).setNum(answer1[i]);
        }

        for (int i = 4; i < 8; i++) {
            list.get(i).setNum(answer2[i -4]);
        }

        for (int i = 8; i < 12; i++) {
            list.get(i).setNum(answer3[i -8]);
        }

        for (int i = 12; i < 16; i++) {
            list.get(i).setNum(answer4[i -12]);
        }

//        int answer4[] = order(4 , 0 , 2, 4);
        drawTextNum();
    }

    /**
     * 排序
     */
    private int[] order(int number1, int number2, int number3, int number4) {
        int nullCount = 0;
        int tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0;
        int[] src = {number1, number2, number3, number4};
        List<Integer> des = new ArrayList<>();
        for (int i = 0; i < src.length; i++) {
            //把数组中不为0的全部添加到des里面
            if (src[i] != 0) {
                des.add(src[i]);
            }
        }
        //如2204 --des里面为224
        //des.size 为0 说明 全部都为0
        //des.size 为1 说明 有一个不为0的
        switch (des.size()) {
            case 0:
                tmp1 = tmp2 = tmp3 = tmp4 = 0;
                break;
            case 1:
                tmp1 = 0;
                tmp2 = 0;
                tmp3 = 0;
                tmp4 = des.get(0);
                break;
            case 2:
                tmp1 = 0;
                tmp2 = 0;
                tmp3 = des.get(0);
                tmp4 = des.get(1);
                break;
            case 3:
                tmp1 = 0;
                tmp2 = des.get(0);
                tmp3 = des.get(1);
                tmp4 = des.get(2);
                break;
            case 4:
                tmp1 = number1;
                tmp2 = number2;
                tmp3 = number3;
                tmp4 = number4;
                break;
        }
        return merge(tmp1, tmp2, tmp3, tmp4);
    }

    /** 取消合并，对merge后的数据排序*/
    private int[] order2(int number1, int number2, int number3, int number4) {
        int nullCount = 0;
        int tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0;
        int[] src = {number1, number2, number3, number4};
        List<Integer> des = new ArrayList<>();
        for (int i = 0; i < src.length; i++) {
            //把数组中不为0的全部添加到des里面
            if (src[i] != 0) {
                des.add(src[i]);
            }
        }
        switch (des.size()) {
            case 0:
                tmp1 = tmp2 = tmp3 = tmp4 = 0;
                break;
            case 1:
                tmp1 = 0;
                tmp2 = 0;
                tmp3 = 0;
                tmp4 = des.get(0);
                break;
            case 2:
                tmp1 = 0;
                tmp2 = 0;
                tmp3 = des.get(0);
                tmp4 = des.get(1);
                break;
            case 3:
                tmp1 = 0;
                tmp2 = des.get(0);
                tmp3 = des.get(1);
                tmp4 = des.get(2);
                break;
            case 4:
                tmp1 = number1;
                tmp2 = number2;
                tmp3 = number3;
                tmp4 = number4;
                break;
        }
        return new int[]{tmp1 , tmp2 , tmp3 , tmp4};
    }

    /**
     * 如2204 向右滑动， 需先左边合并成 00 44  下一步再继续合并2个4
     * 2204到这一步已经变成了0224 //0222这种情况呢//2222这种情况呢//0000这种情况呢
     * //2488这种情况呢
     * 所以合并这一步从右开始
     */
    private int[] merge(int number1, int number2, int number3, int number4) {
        int tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0;
        if (number4 == number3) {
            tmp4 = 2 * number4;
            tmp3 = 0;
            if (number2 == number1) {
                //2222这种情况
                tmp2 = 2 * number2;
                tmp1 = 0;
            } else {
                //0222这种情况
                tmp2 = number2;
                tmp1 = number1;
            }
        }else if (number3 == number2){
            //0224这种情况
            tmp1 = number1;
            tmp2 = 0;
            tmp3 = 2 * number3;
            tmp4 = number4;
        }else if (number2 == number1){
            //2248这种情况  0048
            tmp1 = 0;
            tmp2 = 2 * number2;
            tmp3 = number3;
            tmp4 = number4;
        }else {
            //4024这种情况
            tmp1 = number1;
            tmp2 = number2;
            tmp3 = number3;
            tmp4 = number4;
        }
        return order2(tmp1 , tmp2 , tmp3 , tmp4);
    }


    private void initData() {
        Beans bean11 = new Beans();
        bean11.setHasNum(false);
        bean11.setNum(0);
        bean11.setTv(tv11);
        list.add(bean11);

        Beans bean12 = new Beans();
        bean12.setHasNum(false);
        bean12.setNum(0);
        bean12.setTv(tv12);
        list.add(bean12);

        Beans bean13 = new Beans();
        bean13.setHasNum(false);
        bean13.setNum(0);
        bean13.setTv(tv13);
        list.add(bean13);

        Beans bean14 = new Beans();
        bean14.setHasNum(false);
        bean14.setNum(0);
        bean14.setTv(tv14);
        list.add(bean14);

        Beans bean21 = new Beans();
        bean21.setHasNum(false);
        bean21.setNum(0);
        bean21.setTv(tv21);
        list.add(bean21);

        Beans bean22 = new Beans();
        bean22.setHasNum(false);
        bean22.setNum(0);
        bean22.setTv(tv22);
        list.add(bean22);

        Beans bean23 = new Beans();
        bean23.setHasNum(false);
        bean23.setNum(0);
        bean23.setTv(tv23);
        list.add(bean23);

        Beans bean24 = new Beans();
        bean24.setHasNum(false);
        bean24.setNum(0);
        bean24.setTv(tv24);
        list.add(bean24);

        Beans bean31 = new Beans();
        bean31.setHasNum(false);
        bean31.setNum(0);
        bean31.setTv(tv31);
        list.add(bean31);

        Beans bean32 = new Beans();
        bean32.setHasNum(false);
        bean32.setNum(0);
        bean32.setTv(tv32);
        list.add(bean32);

        Beans bean33 = new Beans();
        bean33.setHasNum(false);
        bean33.setNum(0);
        bean33.setTv(tv33);
        list.add(bean33);

        Beans bean34 = new Beans();
        bean34.setHasNum(false);
        bean34.setNum(0);
        bean34.setTv(tv34);
        list.add(bean34);

        Beans bean41 = new Beans();
        bean41.setHasNum(false);
        bean41.setNum(0);
        bean41.setTv(tv41);
        list.add(bean41);

        Beans bean42 = new Beans();
        bean42.setHasNum(false);
        bean42.setNum(0);
        bean42.setTv(tv42);
        list.add(bean42);

        Beans bean43 = new Beans();
        bean43.setHasNum(false);
        bean43.setNum(0);
        bean43.setTv(tv43);
        list.add(bean43);

        Beans bean44 = new Beans();
        bean44.setHasNum(false);
        bean44.setNum(0);
        bean44.setTv(tv44);
        list.add(bean44);
    }
}
